/* 
 * This code is part of the notepad application, a sample application
 * for the SmartLink project, see
 * 
 * 		http://code.google.com/p/smartlink/.
 * 
 * It is a slightly modified version of the original notepad sample application 
 * distributed by Google as part of the Android SDK, see
 * 
 * 		http://code.google.com/android/samples/NotePad/index.html.
 * 
 * The modifications have the purpose of making the notepad application
 * acting as a "smartlink client" and "smartlink server" application.
 * What this means and the necessary requirements can be found in the documentation
 * of the SmartLink project. 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.notepad;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Resources;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.google.provider.NotePad;

/**
 * Provides access to a database of notes. Each note has a title, the note
 * itself, a creation date and a modified data.
 * 
 */
public class NotePadProvider extends ContentProvider {

	private SQLiteDatabase mDB;

	private static final String TAG = "NotePadProvider";
	private static final String DATABASE_NAME = "note_pad.db";
	private static final int DATABASE_VERSION = 2;

	private static HashMap<String, String> NOTES_LIST_PROJECTION_MAP;

	private static final int NOTES = 1;
	private static final int NOTE_ID = 2;

	private static final UriMatcher URL_MATCHER;

	private static class DatabaseHelper extends SQLiteOpenHelper {

		@Override
		public void onCreate(SQLiteDatabase db) {
			db.execSQL("CREATE TABLE notes (_id INTEGER PRIMARY KEY," + "title TEXT," + "note TEXT,"
					+ "created INTEGER," + "modified INTEGER" + ");");
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion
					+ ", which will destroy all old data");
			db.execSQL("DROP TABLE IF EXISTS notes");
			onCreate(db);
		}
	}

	@Override
	public boolean onCreate() {
		DatabaseHelper dbHelper = new DatabaseHelper();
		mDB = dbHelper.openDatabase(getContext(), DATABASE_NAME, null, DATABASE_VERSION);
		return (mDB == null) ? false : true;
	}

	@Override
	public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs, String sort) {
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

		switch (URL_MATCHER.match(url)) {
		case NOTES:
			qb.setTables("notes");
			qb.setProjectionMap(NOTES_LIST_PROJECTION_MAP);
			break;

		case NOTE_ID:
			qb.setTables("notes");
			qb.appendWhere("_id=" + url.getPathSegments().get(1));
			break;

		default:
			throw new IllegalArgumentException("Unknown URL " + url);
		}

		// If no sort order is specified use the default
		String orderBy;
		if (TextUtils.isEmpty(sort)) {
			orderBy = NotePad.Notes.DEFAULT_SORT_ORDER;
		} else {
			orderBy = sort;
		}

		Cursor c = qb.query(mDB, projection, selection, selectionArgs, null, null, orderBy);
		c.setNotificationUri(getContext().getContentResolver(), url);
		return c;
	}

	@Override
	public String getType(Uri url) {
		switch (URL_MATCHER.match(url)) {
		case NOTES:
			return "vnd.android.cursor.dir/vnd.google.note";

		case NOTE_ID:
			return "vnd.android.cursor.item/vnd.google.note";

		default:
			throw new IllegalArgumentException("Unknown URL " + url);
		}
	}

	@Override
	public Uri insert(Uri url, ContentValues initialValues) {
		long rowID;
		ContentValues values;
		if (initialValues != null) {
			values = new ContentValues(initialValues);
		} else {
			values = new ContentValues();
		}

		if (URL_MATCHER.match(url) != NOTES) {
			throw new IllegalArgumentException("Unknown URL " + url);
		}

		Long now = Long.valueOf(System.currentTimeMillis());
		Resources r = Resources.getSystem();

		// Make sure that the fields are all set
		if (values.containsKey(NotePad.Notes.CREATED_DATE) == false) {
			values.put(NotePad.Notes.CREATED_DATE, now);
		}

		if (values.containsKey(NotePad.Notes.MODIFIED_DATE) == false) {
			values.put(NotePad.Notes.MODIFIED_DATE, now);
		}

		if (values.containsKey(NotePad.Notes.TITLE) == false) {
			values.put(NotePad.Notes.TITLE, r.getString(android.R.string.untitled));
		}

		if (values.containsKey(NotePad.Notes.NOTE) == false) {
			values.put(NotePad.Notes.NOTE, "");
		}

		rowID = mDB.insert("notes", "note", values);
		if (rowID > 0) {
			Uri uri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowID);
			getContext().getContentResolver().notifyChange(uri, null);
			return uri;
		}

		throw new SQLException("Failed to insert row into " + url);
	}

	@Override
	public int delete(Uri url, String where, String[] whereArgs) {
		int count;
		// long rowId = 0;
		switch (URL_MATCHER.match(url)) {
		case NOTES:
			count = mDB.delete("note_pad", where, whereArgs);
			break;

		case NOTE_ID:
			String segment = url.getPathSegments().get(1);
			// rowId = Long.parseLong(segment);
			count = mDB.delete("notes", "_id=" + segment + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""),
					whereArgs);
			break;

		default:
			throw new IllegalArgumentException("Unknown URL " + url);
		}

		getContext().getContentResolver().notifyChange(url, null);
		return count;
	}

	@Override
	public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
		int count;
		switch (URL_MATCHER.match(url)) {
		case NOTES:
			count = mDB.update("notes", values, where, whereArgs);
			break;

		case NOTE_ID:
			String segment = url.getPathSegments().get(1);
			count = mDB.update("notes", values, "_id=" + segment
					+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
			break;

		default:
			throw new IllegalArgumentException("Unknown URL " + url);
		}

		getContext().getContentResolver().notifyChange(url, null);
		return count;
	}

	static {
		URL_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		URL_MATCHER.addURI("com.google.provider.NotePad", "notes", NOTES);
		URL_MATCHER.addURI("com.google.provider.NotePad", "notes/#", NOTE_ID);

		NOTES_LIST_PROJECTION_MAP = new HashMap<String, String>();
		NOTES_LIST_PROJECTION_MAP.put(NotePad.Notes._ID, "_id");
		NOTES_LIST_PROJECTION_MAP.put(NotePad.Notes.TITLE, "title");
		NOTES_LIST_PROJECTION_MAP.put(NotePad.Notes.NOTE, "note");
		NOTES_LIST_PROJECTION_MAP.put(NotePad.Notes.CREATED_DATE, "created");
		NOTES_LIST_PROJECTION_MAP.put(NotePad.Notes.MODIFIED_DATE, "modified");
	}
}
